package xyz.ddlnt.serviceusr.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import xyz.ddlnt.commonutil.enumeration.ResultCode;
import xyz.ddlnt.commonutil.exception.GlobalException;
import xyz.ddlnt.commonutil.util.Argon2Util;
import xyz.ddlnt.commonutil.util.RandomUtil;
import xyz.ddlnt.model.dto.LoginDTO;
import xyz.ddlnt.model.dto.UserInfoDTO;
import xyz.ddlnt.model.entity.UserInfo;
import xyz.ddlnt.model.vo.BloggerInfoVO;
import xyz.ddlnt.model.vo.UserAchieveVO;
import xyz.ddlnt.serviceusr.mapper.UserMapper;
import xyz.ddlnt.serviceusr.service.UserService;

import java.time.LocalDateTime;

/**
 * @author ZZULI_SE 210910
 * @data 2025/5/6 22:47
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserInfo> implements UserService {

    @Resource
    private UserMapper userMapper;
    @Override
    public Boolean login(LoginDTO loginDTO) {
        log.info("loginDTO.toString()");
        log.info(loginDTO.toString());
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUsername, loginDTO.getUsername())
                .select(UserInfo::getId, UserInfo::getPassword);
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        if (userInfo == null) {
            throw new GlobalException(ResultCode.USER_NOT_EXIST);
        }
        if (Argon2Util.verifyPassword(userInfo.getPassword(), loginDTO.getPassword())) {
            StpUtil.login(userInfo.getId());
            return true;
        }
        return false;
    }

    @Override
    public Boolean register(LoginDTO loginDTO) {
        Long id = RandomUtil.generate12DigitRandomNumber();
        String password = Argon2Util.hashPassword(loginDTO.getPassword());
        LocalDateTime registerTime = LocalDateTime.now();
        UserInfo userinfo = UserInfo.builder()
                .id(id)
                .username(loginDTO.getUsername())
                .password(password)
                .registerTime(registerTime)
                .build();
        try {
            userMapper.insert(userinfo);
        }catch (Exception e) {
            log.info("错误信息：{}",e.getCause());
            throw new GlobalException(ResultCode.SERVER_ERROR);
        }
        return true;
    }

    @Override
    public Boolean cancel(LoginDTO loginDTO) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getId, loginDTO.getId())
                .select(UserInfo::getPassword);
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        if (Argon2Util.verifyPassword(userInfo.getPassword(), loginDTO.getPassword())) {
            try {
                userMapper.deleteById(loginDTO.getId());
            }catch (Exception e) {
                log.error("错误信息：{}",e.getCause());
                throw new GlobalException(ResultCode.SERVER_ERROR);
            }
            StpUtil.logout();
            return true;
        }
        return false;
    }

    @Override
    public Boolean updateUserInfoById(UserInfoDTO userInfoDTO) {
        boolean  isPasswordUpdate = false;
        if (!StringUtils.isEmpty(userInfoDTO.getNewPassword()) && !StringUtils.isEmpty(userInfoDTO.getOlderPassword())) {
            LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserInfo::getId, userInfoDTO.getId())
                    .select(UserInfo::getPassword);
            UserInfo userInfo = userMapper.selectOne(queryWrapper);
            if (!Argon2Util.verifyPassword(userInfo.getPassword(), userInfoDTO.getOlderPassword())) {
                throw new GlobalException(ResultCode.USER_PASSWORD_ERROR);
            }
            isPasswordUpdate = true;
        }
        LambdaUpdateWrapper<UserInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserInfo::getId, userInfoDTO.getId())
                .set(!StringUtils.isEmpty(userInfoDTO.getAvatar()), UserInfo::getAvatar, userInfoDTO.getAvatar())
                .set(!StringUtils.isEmpty(userInfoDTO.getUsername()), UserInfo::getUsername, userInfoDTO.getUsername())
                .set(!StringUtils.isEmpty(userInfoDTO.getPersonalIntroduction()), UserInfo::getPersonalIntroduction, userInfoDTO.getPersonalIntroduction())
                .set(!StringUtils.isEmpty(userInfoDTO.getContact()), UserInfo::getContact, userInfoDTO.getContact())
                .set(isPasswordUpdate, UserInfo::getPassword, Argon2Util.hashPassword(userInfoDTO.getNewPassword()));
        return userMapper.update( updateWrapper) == 1;
    }

    @Override
    public BloggerInfoVO getPostBloggerInfo(Long id) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getId, id)
                .select(UserInfo::getUsername, UserInfo::getAvatar, UserInfo::getPersonalIntroduction,
                        UserInfo::getFollowerCount, UserInfo::getLikedCount, UserInfo::getArticleCount);
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        BloggerInfoVO bloggerInfoVO = new BloggerInfoVO();
        BeanUtils.copyProperties(userInfo, bloggerInfoVO);
        return bloggerInfoVO;
    }

    @Override
    public UserAchieveVO getUserAchieve(Long id) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getId, id)
                .select(UserInfo::getUsername, UserInfo::getAvatar, UserInfo::getFollowerCount,
                        UserInfo::getLikedCount, UserInfo::getArticleCount, UserInfo::getCollectedCount,
                        UserInfo::getCommentedCount, UserInfo::getBrowsedCount);
        UserInfo userInfo = userMapper.selectOne(queryWrapper);
        UserAchieveVO userAchieveVO = new UserAchieveVO();
        BeanUtils.copyProperties(userInfo, userAchieveVO);
        return userAchieveVO;
    }
}
